package com.briup.common.utils;

import jakarta.servlet.http.HttpServletRequest;

/**
 * HTTP请求客户端IPv4地址获取工具类
 * 仅返回有效的IPv4地址，忽略IPv6地址
 */
public class IpAddressUtil {

    private IpAddressUtil() {
        throw new AssertionError("工具类不允许实例化");
    }

    /**
     * 获取客户端真实IPv4地址
     *
     * @param request HTTP请求对象
     * @return 客户端真实IPv4地址，如果无法获取则返回"unknown"
     */
    public static String getClientIpAddress(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }

        // 可能的IP地址请求头，按优先级排序
        String[] ipHeaders = {
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_X_FORWARDED_FOR",
                "HTTP_X_FORWARDED",
                "HTTP_X_CLUSTER_CLIENT_IP",
                "HTTP_CLIENT_IP",
                "HTTP_FORWARDED_FOR",
                "HTTP_FORWARDED",
                "HTTP_VIA",
                "REMOTE_ADDR"
        };

        for (String header : ipHeaders) {
            String ip = request.getHeader(header);
            // 只处理有效的IPv4地址
            if (isValidIpv4(ip)) {
                // X-Forwarded-For可能包含多个IP，取第一个有效IPv4
                if ("X-Forwarded-For".equals(header) && ip.contains(",")) {
                    String[] ips = ip.split(",");
                    for (String splitIp : ips) {
                        String trimmedIp = splitIp.trim();
                        if (isValidIpv4(trimmedIp)) {
                            return trimmedIp;
                        }
                    }
                } else {
                    return ip.trim();
                }
            }
        }

        // 最后尝试从请求对象获取
        String remoteAddr = request.getRemoteAddr();
        return isValidIpv4(remoteAddr) ? remoteAddr : "unknown";
    }

    /**
     * 验证是否为有效的IPv4地址
     * IPv4格式：xxx.xxx.xxx.xxx，每个段0-255
     *
     * @param ip 待验证的IP地址
     * @return 如果是有效的IPv4地址则返回true，否则返回false
     */
    private static boolean isValidIpv4(String ip) {
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            return false;
        }

        // IPv4正则：四段数字，每段0-255，且不能以0开头（除非是0本身）
        String ipv4Regex = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

        // 先匹配正则
        if (!ip.matches(ipv4Regex)) {
            return false;
        }

        // 进一步校验每段是否在0-255范围内（正则可能通过类似"999.999.999.999"的情况，需要二次验证）
        String[] parts = ip.split("\\.");
        for (String part : parts) {
            try {
                int num = Integer.parseInt(part);
                if (num < 0 || num > 255) {
                    return false;
                }
            } catch (NumberFormatException e) {
                return false;
            }
        }

        return true;
    }
}
